#include "reader.h"

const char *reader::bufferOverflow::what() const throw(){ 
		
		return "A limit of the reader's buffer was exceed."; 

}

reader::reader(std::istream *file):
	inputFile(file), back(-1), exceptionsBitmask(inputFile->exceptions()), flag(false){

	inputFile->exceptions(std::ios::badbit);
	
}

reader::~reader(){

	inputFile->exceptions(exceptionsBitmask);

}

void reader::read(char *buff, unsigned size){

	inputFile->read(buff, size);
	if(inputFile->eof())
		buff[inputFile->gcount()] = std::ios::eofbit;

}

int reader::getCurrentChar() const{
	
	return buffer[back % (BUFFER_LENGTH * 2)];

}

void reader::initialize() throw(std::ifstream::failure){

	read(buffer, BUFFER_LENGTH);

}

int reader::getChar() throw(std::ifstream::failure){

	int mod = ++back % (BUFFER_LENGTH * 2);

	if(mod == BUFFER_LENGTH && !flag)
		read(buffer + BUFFER_LENGTH, BUFFER_LENGTH);
	else if(mod == 0 && back && !flag)
		read(buffer, BUFFER_LENGTH);
	flag = false;
	return buffer[mod];

}

unsigned long reader::getLength() const{

	return back + 1;

}


void reader::getBack() throw(bufferOverflow){

	if(back == -1)
		throw bufferOverflow();
	flag = true;
	back--;

}

std::string &reader::getString(std::string &lexem, int len) const throw(bufferOverflow){

	std::string buff(len, '\0');
	int i;

	if(len > back || len > BUFFER_LENGTH)
		throw bufferOverflow();
	for(i = 0; i < len; i++)
		buff[i] = buffer[(back - len + i) % (BUFFER_LENGTH * 2)];
	return lexem = buff;

}
